package org.stvd.core.web;

import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;

import org.stvd.core.util.StringUtil;

/**
 * URL工具类
 * 
 * @author sunzhifeng
 * @date 2019/10/30
 */
public class URLUtil {
    private static URL url;
    private static HttpURLConnection con;
    private static int state = -1;

    public static class UrlEntity {
        /**
         * 基础url
         */
        private String baseUrl;
        /**
         * url参数
         */
        private Map<String, String> params;

        public String getBaseUrl() {
            return baseUrl;
        }

        public void setBaseUrl(String baseUrl) {
            this.baseUrl = baseUrl;
        }

        public Map<String, String> getParams() {
            return params;
        }

        public void setParams(Map<String, String> params) {
            this.params = params;
        }
    }

    /**
     * 解析url
     *
     * @param url
     * @return
     */
    public static UrlEntity parse(String url) {
        UrlEntity entity = new UrlEntity();
        if (url == null) {
            return entity;
        }
        String urlAll = url.trim();
        if ("".equals(urlAll)) {
            return entity;
        }
        String[] urlParts = urlAll.split("\\?");
        entity.setBaseUrl(urlParts[0]);
        // 没有参数
        if (urlParts.length == 1) {
            return entity;
        }
        // 有参数
        String[] params = urlParts[1].split("&");
        entity.setParams(new HashMap<>());
        for (String param : params) {
            String[] keyValue = param.split("=");
            entity.getParams().put(keyValue[0], keyValue[1]);
        }

        return entity;
    }

    /**
     * 功能：检测当前URL是否可连接或是否有效, 描述：最多连接网络 5 次, 如果 5 次都不成功，视为该地址不可用
     * 
     * @param urlStr
     *            指定URL网络地址
     * @return URL
     */
    public static synchronized URL isValid(String urlStr) {
        int counts = 0;
        if (urlStr == null || urlStr.length() <= 0) {
            return null;
        }
        String urlTmp = urlStr;
        while (counts < 5) {
            try {
                url = new URL(urlTmp);
                con = (HttpURLConnection) url.openConnection();
                state = con.getResponseCode();
                System.out.println(counts + "= " + state);
                if (state == 200) {
                    System.out.println("URL可用！");
                    return url;
                }
                break;
            } catch (Exception ex) {
                counts++;
                System.out.println("URL不可用，连接第 " + counts + " 次");
                urlTmp = null;
                ex.printStackTrace();
                continue;
            }
        }
        return null;
    }

    public static String getURL(HttpServletRequest request) {
        // 请求地址
        if (request.getMethod() != null && request.getRequestURL() != null) {
            String requestUrl = "[" + request.getMethod() + "]" + request.getRequestURL();
            if (request.getQueryString() != null && !"".equals(request.getQueryString())) {
                try {
                    requestUrl += "?" + new String(request.getQueryString().getBytes("ISO-8859-1"), "UTF-8");
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
            }
            return requestUrl;
        }
        return "";
    }

    private static String getContextPath25(ServletContext context) {
        String contextPath = context.getContextPath();

        if (contextPath == null || contextPath.length() == 0) {
            contextPath = "/";
        }

        return contextPath;
    }

    public static String getContextPath(ServletContext context) {
        if (context.getMajorVersion() == 2 && context.getMinorVersion() < 5) {
            return null;
        }

        try {
            return getContextPath25(context);
        } catch (NoSuchMethodError error) {
            return null;
        }
    }

    /**
     * 在指定url后追加参数
     * 
     * @param url
     * @param data
     *            参数集合 key = value
     * @return
     */
    public static String appendUrl(String url, Map<String, String> data) {
        String newUrl = url;
        StringBuffer param = new StringBuffer();
        Iterator<Entry<String, String>> entryKeyIterator = data.entrySet().iterator();
        while (entryKeyIterator.hasNext()) {
            Entry<String, String> entry = entryKeyIterator.next();
            String key = entry.getKey();
            param.append(key + "=" + data.get(key).toString() + "&");
        }
        String paramStr = param.toString();
        if (!StringUtil.isEmpty(paramStr)) {
            paramStr = paramStr.substring(0, paramStr.length() - 1);
            if (newUrl.indexOf('?') >= 0) {
                newUrl += "&" + paramStr;
            } else {
                newUrl += "?" + paramStr;
            }
        }
        
        return newUrl;
    }

    /**
     * 获取指定url中的某个参数
     * 
     * @param url
     * @param name
     * @return
     */
    public static String getParamByUrl(String url, String name) {
        String newUrl = url + "&";
        String pattern = "(\\?|&){1}#{0,1}" + name + "=[a-zA-Z0-9]*(&{1})";

        Pattern r = Pattern.compile(pattern);

        Matcher m = r.matcher(newUrl);
        if (m.find()) {
            System.out.println(m.group(0));
            return m.group(0).split("=")[1].replace("&", "");
        } else {
            return null;
        }
    }
}
